package com.stellar.circle.task;


import com.stellar.circle.basic.entity.SPost;
import com.stellar.circle.basic.service.SPostService;
import com.stellar.circle.redis.RedisCacheKey;
import com.stellar.redis.core.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static com.stellar.circle.constants.CircleConstants.IS_PINNED;
import static com.stellar.circle.constants.CircleConstants.NOT_PINNED;


/**
 * @Author: Jqchan_
 */

@Component
@Slf4j
public class PostPinTask {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private SPostService sPostService;

    /**
     * 置顶任务
     */
    @Scheduled(fixedRate = 60000) // 每分钟执行一次
    public void processPinQueue() {
        log.info("开始执行置顶任务");
        //  扫描需要开始置顶的帖子
        long now = System.currentTimeMillis();

        // 获取所有到期的帖子ID
        Set<String> postIds = redisUtil.rangeByScore(
                RedisCacheKey.POST_PIN_QUEUE.getCachePrefix(), 0, now);

        if (postIds == null || postIds.isEmpty()) {
            return;
        }

        log.info("待处理的帖子数量: {}", postIds.size());

        for (String postId : postIds) {

            // 从Redis获取置顶信息
            String pinKey = redisUtil.buildKey(RedisCacheKey.POST_PIN.getCachePrefix(), postId);
            Map<Object, Object> pinMap = redisUtil.entries(pinKey);

            if (pinMap.isEmpty()) {
                redisUtil.removeZset(RedisCacheKey.POST_PIN_QUEUE.getCachePrefix(), postId);
                continue;
            }

            // 执行置顶操作
            Date endTime = new Date((Long) pinMap.get("endTime"));

            SPost sPost = sPostService.queryById(Long.valueOf(postId));
            sPost.setIsPinned(IS_PINNED);
            sPost.setPinExpireTime(endTime);
            sPostService.update(sPost);

            log.info("置顶成功，帖子ID: {}", postId);

            // 更新帖子缓存
//            refreshPostCache(postId);

            // 从队列中移除
            String postIdStr = String.valueOf(postId);
            redisUtil.removeZset(RedisCacheKey.POST_PIN_QUEUE.getCachePrefix(), postIdStr);

            // 添加到期检查（可选用新的ZSET记录到期时间）
            addToExpirationQueue(postId, endTime.getTime());
        }
    }

    // 添加到到期队列（使用ZSET）
    private void addToExpirationQueue(String postId, long expireTimestamp) {
        redisUtil.zAdd(RedisCacheKey.POST_PIN_EXPIRE_QUEUE.getCachePrefix(), postId, expireTimestamp);

        // 设置队列过期时间
        redisUtil.expire(RedisCacheKey.POST_PIN_EXPIRE_QUEUE.getCachePrefix(), 30L, TimeUnit.DAYS);
    }


    /**
     * 置顶到期检查任务
     */
    @Scheduled(fixedRate = 30000) // 每30秒执行一次
    public void checkPinExpiration() {
        log.info("开始执行置顶到期检查任务");

        long now = System.currentTimeMillis();

        Set<String> expiredIds = redisUtil.rangeByScore(
                RedisCacheKey.POST_PIN_EXPIRE_QUEUE.getCachePrefix(), 0, now);

        if (expiredIds == null || expiredIds.isEmpty()) {
            return;
        }

        for (String postIdStr : expiredIds) {
            Long postId = Long.parseLong(postIdStr);
            try {

                // 取消置顶
                SPost sPost = sPostService.queryById(postId);
                sPost.setIsPinned(NOT_PINNED);
                sPostService.update(sPost);

                log.info("取消置顶成功，帖子ID: {}", postId);

                // 清理Redis数据
                String pinKey = redisUtil.buildKey(RedisCacheKey.POST_PIN.getCachePrefix(), postId.toString());
                redisUtil.del(pinKey);

                // 更新缓存
//                refreshPostCache(postId);

            } catch (Exception e) {
                log.error("处理置顶到期异常: postId={}, error={}", postIdStr, e.getMessage());

            } finally {
                // 从队列中移除
                redisUtil.removeZset(RedisCacheKey.POST_PIN_EXPIRE_QUEUE.getCachePrefix(), postIdStr);
            }

        }
    }

}
